package com.sisgesbyte.services.proyeccion;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.inject.Inject;

import com.sisgesbyte.common.ConstModAdministracion;
import com.sisgesbyte.common.ConstProyeccion;
import com.sisgesbyte.common.ConstantesInternasSistema;
import com.sisgesbyte.common.Validaciones;
import com.sisgesbyte.dao.beanDao.FiltrosBean;
import com.sisgesbyte.dao.beanDao.FiltrosSQLBean;
import com.sisgesbyte.dao.beanDao.ProyeccionCatClienteDetalleRequest;
import com.sisgesbyte.dao.proyeccion.MantProyeccionCatClienteDetDao;
import com.sisgesbyte.data.entity.comun.GenericEntity;
import com.sisgesbyte.data.entity.proyeccion.ProyeccionCatClienteDetEntity;
import com.sisgesbyte.services.commonBean.GenericGuardarResponse;
import com.sisgesbyte.services.commonBean.GenericResponse;
import com.sisgesbyte.services.proyeccion.bean.FiltroOpcionesCanalBean;
import com.sisgesbyte.services.proyeccion.bean.ListaProyCategoriaClienteResponse;
import com.sisgesbyte.services.proyeccion.bean.ListaProyeccionCatClienteDetalleResponse;
import com.sisgesbyte.services.proyeccion.bean.ProyeccionCatClienteDetalleBean;
import com.sisgesbyte.services.proyeccion.bean.ProyeccionCategoriaClienteBean;

@Stateless
public class MantProyeccionCanalDetalleServiceImpl implements
		MantProyeccionCanalDetalleService {

	@EJB
	private MantProyeccionCatClienteDetDao mantProyeccionCatClienteDetDao;
	@EJB 
	private MantProyeccionCanalService mantProyeccionCanalService;
	@Inject
	private Validaciones validaciones;
	
	@Override
	public ListaProyeccionCatClienteDetalleResponse listaProyeccionCatClienteDetalle( String codTransaccion, FiltroOpcionesCanalBean filtroBean) {
		String mensajeTransaccionMetodo = "[listaCatClientes idTx=" + codTransaccion + "] - ";
		ListaProyeccionCatClienteDetalleResponse response = new ListaProyeccionCatClienteDetalleResponse();
		
		List<ProyeccionCatClienteDetEntity> listaProyCanales = null;
		try{
			FiltrosSQLBean filtroSQL = new FiltrosSQLBean();
			List<Object> valores = new ArrayList<>();
			List<FiltrosBean> filtro = new ArrayList<FiltrosBean>();

			if(filtroBean.getZonaId() > 0){
				FiltrosBean listaZona = new FiltrosBean();
				List<String> campoZona = new ArrayList<String>();
				campoZona.add("pcc.zona_id");
				listaZona.setCampos(campoZona);
				listaZona.setOperador("=");
				filtro.add(listaZona);
				valores.add(filtroBean.getZonaId());
			}
			
			if(filtroBean.getPeriodoId() > 0){
				FiltrosBean listaPeriodo = new FiltrosBean();
				List<String> campoPeriodo = new ArrayList<String>();
				campoPeriodo.add("pcc.periodo_id");
				listaPeriodo.setCampos(campoPeriodo);
				listaPeriodo.setOperador("=");
				filtro.add(listaPeriodo);
				valores.add(filtroBean.getPeriodoId());
			}
			
			if(filtroBean.getCanalId() > 0){
				FiltrosBean listaCanal = new FiltrosBean();
				List<String> campoCanal = new ArrayList<String>();
				campoCanal.add("pcc.categoria_cliente_id");
				listaCanal.setCampos(campoCanal);
				listaCanal.setOperador("=");
				filtro.add(listaCanal);
				valores.add(filtroBean.getCanalId());
			}
			
			if(filtroBean.getTxtBuscar() !=null){
				if(filtroBean.getTxtBuscar().trim().length() > 0){
					// filtro por String
						FiltrosBean listaCampo = new FiltrosBean();
						List<String> campo = new ArrayList<String>();
						campo.add("pccd.id");
						campo.add("m.marca");
						campo.add("p.cod_prod");
						campo.add("p.producto");
						campo.add("cp.nombre");
						listaCampo.setCampos(campo);
						listaCampo.setOperador("like");
						filtro.add(listaCampo);
						valores.add("%" + filtroBean.getTxtBuscar() + "%");
				}
					// -------------------
			}
			filtroSQL.setListaFiltros(filtro);
			filtroSQL.setListaValores(valores);
			
			listaProyCanales = mantProyeccionCatClienteDetDao.proyeccionCatClienteDetalle(filtroSQL);
			
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo + "Hubo un error al listar de  BD " + e);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDT);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDT);
			return response;
		}
		
		if(listaProyCanales.size() > 0){
			List<ProyeccionCatClienteDetalleBean> listaProyClienteDetalle = new ArrayList<ProyeccionCatClienteDetalleBean>();
			for(ProyeccionCatClienteDetEntity ls :listaProyCanales ){
				ProyeccionCatClienteDetalleBean bean = new ProyeccionCatClienteDetalleBean();
				bean.setCantidadProyectada(ls.getCantidad_proyectada());
				bean.setCategoriaClienteId(ls.getCategoria_cliente_id());
				bean.setCanal(validaciones.validarCamposString(ls.getCanal()));
				bean.setCategoriaProducto(validaciones.validarCamposString(ls.getCategoria_producto()));
				bean.setCategoriaProductoId(ls.getCategoria_producto_id());
				bean.setCodigoBanda(validaciones.validarCamposString(ls.getCodigo_banda()));
				bean.setCodProd(validaciones.validarCamposString(ls.getCod_prod()));
				bean.setId(ls.getId());
				bean.setMarca(validaciones.validarCamposString(ls.getMarca()));
				bean.setMarcaId(ls.getMarca_id());
				bean.setPeriodoId(ls.getPeriodo_id());
				bean.setPrecioPromedio(ls.getPrecio_promedio());
				bean.setProducto(validaciones.validarCamposString(ls.getProducto()));
				bean.setProductoId(ls.getProducto_id());
				bean.setProyeccionCategoriaClienteId(ls.getProyeccion_categoria_cliente_id());
				bean.setZonaId(ls.getZona_id());
				
				listaProyClienteDetalle.add(bean);
			}
			
			response.setIdTransaccion(codTransaccion);
			response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
			response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
			response.setListaProyClienteDetalle(listaProyClienteDetalle);
			
		}else{
			response.setIdTransaccion(codTransaccion);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDF);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDF);
		}
		
		return response;
	}

	@Override
	public GenericResponse nuevaProyeccioCatClienteDetalle(
			String codTransaccion, ProyeccionCatClienteDetalleBean request) {
		String mensajeTransaccionMetodo = "[nuevaProyeccioCatClienteDetalle idTx=" + codTransaccion + "] - ";
		GenericResponse response = new GenericResponse();
		
		
		boolean existe = false;
		String codigoBanda="";
		int idProyeccionCanal = 0;
		try{
			FiltroOpcionesCanalBean filtro = new FiltroOpcionesCanalBean();
			filtro.setCanalId(request.getCategoriaClienteId());
			filtro.setPeriodoId(request.getPeriodoId());
			filtro.setZonaId(request.getZonaId());
		//1.- verificamos si existe la proyeccion de este canal por monto
			ListaProyCategoriaClienteResponse listaProyeccionCanales = mantProyeccionCanalService.listaCatClientes(codTransaccion, filtro);
			System.out.println("Respuesta Busqueda CAnal: " + listaProyeccionCanales.getCodigoRespuesta());
			if(listaProyeccionCanales.getCodigoRespuesta().equalsIgnoreCase(ConstantesInternasSistema.CODIGO_EXITO)){
				existe = true;
				for(ProyeccionCategoriaClienteBean ls : listaProyeccionCanales.getListaProyeccionCategoriaCliente()){
					idProyeccionCanal = ls.getId();
					codigoBanda = validaciones.validarCamposString(ls.getBandaPeriodo());
				}
			}
			
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo + "Hubo un error al listar la proyeccion de canal" + e);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDT);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDT);
			return response;
		}
		
		if(!existe){
			//2.- si no existe la proyeccion del canal por monto, la registramos y obtenemos el Id
			try{
				ProyeccionCategoriaClienteBean req = new ProyeccionCategoriaClienteBean();
				req.setPeriodoId(request.getPeriodoId());
				req.setCategoriaClienteId(request.getCategoriaClienteId());
				req.setZonaId(request.getZonaId());
				req.setMontoProyectado(BigDecimal.ZERO);
				req.setBandaPeriodo(" ");
				GenericGuardarResponse nuevoProyCanal  = mantProyeccionCanalService.nuevaProyeccionCategoriaCliente(codTransaccion, req);
				System.out.println("Respuesta Registro CAnal: " + nuevoProyCanal.getCodigoRespuesta());
				if(nuevoProyCanal.getCodigoRespuesta().equalsIgnoreCase(ConstantesInternasSistema.CODIGO_EXITO)){
					idProyeccionCanal = Integer.valueOf(nuevoProyCanal.getCodigoSaved());
				}else{
					System.out.println("No se registro correctamente la proyeccion del canal ");
					response.setCodigoRespuesta(nuevoProyCanal.getCodigoRespuesta());
					response.setMensajeRespuesta(nuevoProyCanal.getMensajeRespuesta());
					return response;
				}
			}catch(Exception e){
				System.out.println("Error tecnico: No se registro correctamente la proyeccion del canal ");
				response.setCodigoRespuesta(ConstModAdministracion.MANT_NUEVO_COD_IDT);
				response.setMensajeRespuesta(ConstModAdministracion.MANT_NUEVO_MSJ_IDT);
				return response;
			}
		}
		
		try{
			ProyeccionCatClienteDetalleRequest req = new ProyeccionCatClienteDetalleRequest();
			
			req.setCantidadProyectada(request.getCantidadProyectada());
			req.setCodigo_banda(validaciones.validarCamposString(request.getCodigoBanda()));
			req.setProductoId(request.getProductoId());
			req.setProyeccionCategoriaClienteId(idProyeccionCanal);
			//3.- Insertamos la proyeccion del canal detalle
			GenericEntity nuevaProy = mantProyeccionCatClienteDetDao.guardarProyeccionCategoriaClienteDet(req);
			System.out.println("Respuesta Registro CAnal Detalle: " + nuevaProy.getCod_error());
			if(nuevaProy.getCod_error() == Integer.valueOf(ConstantesInternasSistema.CODIGO_EXITO)){
				
				//4.- obtemos la suma de la proyeccion de acuerdo al filtro
				BigDecimal totalProyeccion = null;
				try{
					FiltroOpcionesCanalBean filtro = new FiltroOpcionesCanalBean();
					filtro.setCanalId(request.getCategoriaClienteId());
					filtro.setPeriodoId(request.getPeriodoId());
					filtro.setZonaId(request.getZonaId());
					totalProyeccion =  montoTotalProyeccion(codTransaccion, filtro);
					System.out.println("Total Proyeccion Onbtenido " + totalProyeccion);
				}catch(Exception e){
					System.out.println(mensajeTransaccionMetodo + "Error al obtener la suma de la proyeccion del canal detalle " + e);
					response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDT);
					response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDT);
					return response;
				}
				
				//5.- actualizamos la proyeccion total del canal 
				
				try{
					ProyeccionCategoriaClienteBean reqCanal = new ProyeccionCategoriaClienteBean();
					reqCanal.setId(idProyeccionCanal);
					reqCanal.setCategoriaClienteId(request.getCategoriaClienteId());
					reqCanal.setPeriodoId(request.getPeriodoId());
					reqCanal.setZonaId(request.getZonaId());
					reqCanal.setBandaPeriodo(codigoBanda);
					reqCanal.setMontoProyectado(totalProyeccion);
					
					GenericResponse actualizarProyCliente = mantProyeccionCanalService.editarProyeccionCategoriaCliente(codTransaccion, reqCanal);
					System.out.println("Respuesta Actualizacion CAnal Monto: " + actualizarProyCliente.getCodigoRespuesta());
					if(actualizarProyCliente.getCodigoRespuesta().equalsIgnoreCase(ConstantesInternasSistema.CODIGO_EXITO)){
						System.out.println("Se registro correctamente la proyeccion ");
						response.setIdTransaccion(codTransaccion);
						response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
						response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
					}else{
						System.out.println("IDF: Hubo un error al actualizar el monto de la proyeccion del canal");
						response.setCodigoRespuesta(actualizarProyCliente.getCodigoRespuesta());
						response.setMensajeRespuesta(actualizarProyCliente.getMensajeRespuesta());
					}
					
				}catch(Exception e){
					System.out.println(mensajeTransaccionMetodo + "Hubo un error al actualizar el monto de la proyeccion del canal " + e);
					response.setCodigoRespuesta(ConstModAdministracion.MANT_NUEVO_COD_IDT);
					response.setMensajeRespuesta(ConstModAdministracion.MANT_NUEVO_MSJ_IDT);
					return response;
				}
				
			}else{
				System.out.println("IDf: Error al registrar el detalle de la produccion ");
				response.setCodigoRespuesta(String.valueOf(nuevaProy.getCod_error()));
				response.setMensajeRespuesta(nuevaProy.getMsj_error());
				
			}
			
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo + "Hubo un error al registrar la Proyeccion en BD " + e);
			response.setCodigoRespuesta(ConstModAdministracion.MANT_NUEVO_COD_IDT);
			response.setMensajeRespuesta(ConstModAdministracion.MANT_NUEVO_MSJ_IDT);
		}
		
		return response;
	}

	@Override
	public GenericResponse editarProyeccionCatClienteDetalle(
			String codTransaccion, ProyeccionCatClienteDetalleBean request) {
		String mensajeTransaccionMetodo = "[editarProyeccionCatClienteDetalle idTx=" + codTransaccion + "] - ";
		GenericResponse response = new GenericResponse();
		
		try{
			ProyeccionCatClienteDetalleRequest req = new ProyeccionCatClienteDetalleRequest();
			req.setId(request.getId());
			req.setCantidadProyectada(request.getCantidadProyectada());
			req.setCodigo_banda(validaciones.validarCamposString(request.getCodigoBanda()));
			req.setProductoId(request.getProductoId());
			req.setProyeccionCategoriaClienteId(request.getProyeccionCategoriaClienteId());
			
			GenericEntity editProy = mantProyeccionCatClienteDetDao.actualizarProyeccionCategoriaClienteDet(req);
			
			if(editProy.getCod_error() == Integer.valueOf(ConstantesInternasSistema.CODIGO_EXITO)){
				
				//1.- obtemos la suma de la proyeccion de acuerdo al filtro
				BigDecimal totalProyeccion = null;
				try{
					FiltroOpcionesCanalBean filtro = new FiltroOpcionesCanalBean();
					filtro.setCanalId(request.getCategoriaClienteId());
					filtro.setPeriodoId(request.getPeriodoId());
					filtro.setZonaId(request.getZonaId());
					totalProyeccion =  montoTotalProyeccion(codTransaccion, filtro);
				}catch(Exception e){
					System.out.println(mensajeTransaccionMetodo + "Error al obtener la suma de la proyeccion del canal detalle " + e);
					response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDT);
					response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDT);
					return response;
				}
				
				//2.- actualizamos la proyeccion total del canal 
				
				try{
					ProyeccionCategoriaClienteBean reqCanal = new ProyeccionCategoriaClienteBean();
					reqCanal.setId(request.getProyeccionCategoriaClienteId());
					reqCanal.setCategoriaClienteId(request.getCategoriaClienteId());
					reqCanal.setPeriodoId(request.getPeriodoId());
					reqCanal.setZonaId(request.getZonaId());
					reqCanal.setBandaPeriodo("");//esto significa que no me actualizara la banda, asi esta configurado el SP
					reqCanal.setMontoProyectado(totalProyeccion);
					
					GenericResponse actualizarProyCliente = mantProyeccionCanalService.editarProyeccionCategoriaCliente(codTransaccion, reqCanal);
					
					if(actualizarProyCliente.getCodigoRespuesta().equalsIgnoreCase(ConstantesInternasSistema.CODIGO_EXITO)){
						System.out.println("Se actualizo correctamente la proyeccion ");
						response.setIdTransaccion(codTransaccion);
						response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
						response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
					}else{
						System.out.println("IDF: Hubo un error al actualizar el monto de la proyeccion del canal");
						response.setCodigoRespuesta(ConstModAdministracion.MANT_NUEVO_COD_IDF);
						response.setMensajeRespuesta(ConstModAdministracion.MANT_NUEVO_MSJ_IDF);
					}
					
				}catch(Exception e){
					System.out.println(mensajeTransaccionMetodo + "Hubo un error al actualizar el monto de la proyeccion del canal " + e);
					response.setCodigoRespuesta(ConstModAdministracion.MANT_NUEVO_COD_IDT);
					response.setMensajeRespuesta(ConstModAdministracion.MANT_NUEVO_MSJ_IDT);
					return response;
				}
				
			}else{
				response.setCodigoRespuesta(String.valueOf(editProy.getCod_error()));
				response.setMensajeRespuesta(editProy.getMsj_error());
			}
			
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo + "Hubo un error al registrar la Proyeccion en BD " + e);
			response.setCodigoRespuesta(ConstModAdministracion.MANT_NUEVO_COD_IDT);
			response.setMensajeRespuesta(ConstModAdministracion.MANT_NUEVO_MSJ_IDT);
		}
		
		return response;
	}

	@Override
	public GenericResponse deleteProyeccionCatClienteDetalle(
			String codTransaccion, ProyeccionCatClienteDetalleBean request) {
		String mensajeTransaccionMetodo = "[deleteProyeccionCatClienteDetalle idTx=" + codTransaccion + "] - ";
		GenericResponse response = new GenericResponse();
		
		try{
			GenericEntity deleteProy = mantProyeccionCatClienteDetDao.eliminarProyeccionCategoriaClienteDet(request.getId());
			
			if(deleteProy.getCod_error() == Integer.valueOf(ConstantesInternasSistema.CODIGO_EXITO)){
				//1.- obtemos la suma de la proyeccion de acuerdo al filtro
				BigDecimal totalProyeccion = null;
				try{
					FiltroOpcionesCanalBean filtro = new FiltroOpcionesCanalBean();
					filtro.setCanalId(request.getCategoriaClienteId());
					filtro.setPeriodoId(request.getPeriodoId());
					filtro.setZonaId(request.getZonaId());
					totalProyeccion =  montoTotalProyeccion(codTransaccion, filtro);
				}catch(Exception e){
					System.out.println(mensajeTransaccionMetodo + "Error al obtener la suma de la proyeccion del canal detalle " + e);
					response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDT);
					response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDT);
					return response;
				}
				
				//2.- actualizamos la proyeccion total del canal 
				
				try{
					ProyeccionCategoriaClienteBean reqCanal = new ProyeccionCategoriaClienteBean();
					reqCanal.setId(request.getProyeccionCategoriaClienteId());
					reqCanal.setCategoriaClienteId(request.getCategoriaClienteId());
					reqCanal.setPeriodoId(request.getPeriodoId());
					reqCanal.setZonaId(request.getZonaId());
					reqCanal.setBandaPeriodo("");//esto significa que no me actualizara la banda, asi esta configurado el SP
					reqCanal.setMontoProyectado(totalProyeccion);
					
					GenericResponse actualizarProyCliente = mantProyeccionCanalService.editarProyeccionCategoriaCliente(codTransaccion, reqCanal);
					
					if(actualizarProyCliente.getCodigoRespuesta().equalsIgnoreCase(ConstantesInternasSistema.CODIGO_EXITO)){
						System.out.println("Se elimino correctamente la proyeccion ");
						response.setIdTransaccion(codTransaccion);
						response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
						response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
					}else{
						System.out.println("IDF: Hubo un error al actualizar el monto de la proyeccion del canal");
						response.setCodigoRespuesta(ConstModAdministracion.MANT_NUEVO_COD_IDF);
						response.setMensajeRespuesta(ConstModAdministracion.MANT_NUEVO_MSJ_IDF);
					}
					
				}catch(Exception e){
					System.out.println(mensajeTransaccionMetodo + "Hubo un error al actualizar el monto de la proyeccion del canal " + e);
					response.setCodigoRespuesta(ConstModAdministracion.MANT_NUEVO_COD_IDT);
					response.setMensajeRespuesta(ConstModAdministracion.MANT_NUEVO_MSJ_IDT);
					return response;
				}
			}else{
				response.setCodigoRespuesta(String.valueOf(deleteProy.getCod_error()));
				response.setMensajeRespuesta(deleteProy.getMsj_error());
			}
			
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo + "Hubo un error al registrar la Proyeccion en BD " + e);
			response.setCodigoRespuesta(ConstModAdministracion.MANT_NUEVO_COD_IDT);
			response.setMensajeRespuesta(ConstModAdministracion.MANT_NUEVO_MSJ_IDT);
		}
		
		return response;
	}

	public BigDecimal montoTotalProyeccion(String codTransaccion, FiltroOpcionesCanalBean filtroBean){
		String mensajeTransaccionMetodo = "[montoTotalProyeccion idTx=" + codTransaccion + "] - ";
		BigDecimal monto = BigDecimal.ZERO;
		
		try{
			ListaProyeccionCatClienteDetalleResponse response = listaProyeccionCatClienteDetalle( codTransaccion, filtroBean);
			
			if(response.getCodigoRespuesta().equalsIgnoreCase(ConstantesInternasSistema.CODIGO_EXITO)){
				for(ProyeccionCatClienteDetalleBean ls : response.getListaProyClienteDetalle()){
					monto = monto.add(ls.getCantidadProyectada().multiply(ls.getPrecioPromedio()));
				}
			}
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo + "Error al obtener el monto de la proyeccio " + e);
			monto= BigDecimal.ZERO;
		}
		
		return monto;
	}
}
